﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RuoTeng.Win32
{
    class KeyBoard:Message
    {

        public const uint WM_KEYDOWN=0x0100;
        public const uint WM_KEYUP  =0x0101;
        public const uint WM_CHAR   =0x0102;

       /// <summary>
       /// 模拟组合键如 Ctrl+V
       /// </summary>
       /// <param name="hWnd">目标句柄</param>
       /// <param name="primaryKey">辅助键</param>
       /// <param name="secondKey">非辅助键</param>
        public static void CombineKey(IntPtr hWnd,VirtualKeys primaryKey, VirtualKeys secondKey)
        {
            PostMessage(hWnd, WM_KEYDOWN, (int)primaryKey, 0x001D0001);          
            PostMessage(hWnd, WM_KEYDOWN, (int)secondKey,  0x002F0001);
           
            PostMessage(hWnd, WM_KEYUP, (int)secondKey,  0xC02F0001);
            PostMessage(hWnd, WM_KEYUP, (int)primaryKey, 0xC01D0001);
        }

        /// <summary>
        /// 将Acsii码转换成虚拟键码
        /// </summary>
        /// <param name="code">Acsii码</param>
        /// <param name="helpKey">是否配合辅助键如Ctrl Shilt等键</param>
        /// <returns>返回虚拟键码</returns>
        static int GetVirtualKeys(int code,out int helpKey)
        {
            int VK = code; helpKey = 0;
            if (0x60 <code && code < 0x7B)
            {
                VK -= 26;
            }
            else
            {
                bool shift = false;
                switch (code)
                {
                    case 0x21: VK = 0x31; shift = true; break;
                    case 0x22: VK = 0x27; shift = true; break;
                    case 0x23: VK = 0x33; shift = true; break;
                    case 0x24: VK = 0x34; shift = true; break;
                    case 0x45: VK = 0x35; shift = true; break;
                    case 0x26: VK = 0x37; shift = true; break;
                    case 0x28: VK = 0x39; shift = true; break;
                    case 0x29: VK = 0x30; shift = true; break;
                    case 0x30: VK = 0x38; shift = true; break;
                    case 0x31: VK = 0x3D; shift = true; break;
                    case 0x3A: VK = 0x3B; shift = true; break;
                    case 0x3C: VK = 0x2C; shift = true; break;
                    case 0x3E: VK = 0x2E; shift = true; break;
                    case 0x3F: VK = 0x2F; shift = true; break;
                    case 0x40: VK = 0x32; shift = true; break;
                    case 0x5E: VK = 0x36; shift = true; break;
                    case 0x5F: VK = 0x2D; shift = true; break;
                    case 0x7B: VK = 0x5B; shift = true; break;
                    case 0x7C: VK = 0x5C; shift = true; break;
                    case 0x7D: VK = 0x5D; shift = true; break;
                    case 0x7E: VK = 0x60; shift = true; break;
                }
                if (shift) helpKey = (int)VirtualKeys.VK_SHIFT;
            }
            return VK;
        }

        /// <summary>
        /// 键盘按下/抬起操作一个完成动作
        /// </summary>
        /// <param name="hWnd">发送消息目标句柄</param>
        /// <param name="code">Ascii码</param>
        public static void PressKey(IntPtr hWnd,int code)
        {   
            int helpKey;
            int VK=GetVirtualKeys(code,out helpKey);
        //检测该字符是否需要辅助键
            if(helpKey>0)
            {
               SendMessage(hWnd,WM_KEYDOWN,helpKey,0);
            }
            SendMessage(hWnd, WM_KEYDOWN, VK,   0);
            SendMessage(hWnd, WM_CHAR,    code, 0);
            SendMessage(hWnd, WM_KEYUP,   VK,   0x40000000);
        //检测该字符是否需要辅助键
            if (helpKey>0)
            {
                SendMessage(hWnd, WM_KEYDOWN, helpKey, 0);
            }
        }

    }
}
